/**
 * @author Ethan
 */
package com.u2ds.core.util.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Map;

import org.springframework.util.StringUtils;

/**
 * @author Ethan
 * @date 下午7:01:02
 * @email windofdusk@gmail.com
 * 类说明
 */
@SuppressWarnings({"unchecked", "rawtypes"})
public class ReflectExtUtil {
	
	/**
	 * 
	 * @param target 目标实例
	 * @param fname 要设置的属性名
	 * @param ftype 要设置的属性类型
	 * @param fvalue 要设置的值
	 * @throws Exception
	 */
	public static void setFieldValue(Object target, String fname, Class ftype, Object fvalue) throws Exception{
		if(target == null 
			   || fname == null
			   || "".equals(fname)
			   || (fvalue != null && !ftype.isAssignableFrom(fvalue.getClass()))){
			return;
		}
		
		Class clazz = target.getClass();
		try{
			//有set方法调用set方法
			Method method = clazz.getDeclaredMethod("set" + StringUtils.capitalize(fname),ftype);
			if(!Modifier.isPublic(method.getModifiers())){
				method.setAccessible(true);
			}
			method.invoke(target, fvalue);
		}catch(Exception me){
			//木有set方法怎么办
			try{
				Field field = clazz.getDeclaredField(fname);
				if(!Modifier.isPublic(field.getModifiers())){
					field.setAccessible(true);
				}
				field.set(target, fvalue);
			}catch(Exception e){
				throw e;
			}
		}
	}
	
	/**
	 * 仅列出有get方法的属性
	 * @param target
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> getMapFieldData(Object target) throws Exception{
		Map<String, Object> map = new HashMap<String, Object>();
		Class clazz = target.getClass();
		Field[] fields = clazz.getDeclaredFields();
		Method[] methods = clazz.getDeclaredMethods();
		for(Field field : fields){
			String fieldName = field.getName();
			String getMethod = "get" + StringUtils.capitalize(fieldName);
			for(Method method : methods){
				if(method.getName().equals(getMethod)){
					try {
                        Object ret = method.invoke(target, new Object[]{});
                        map.put(fieldName, ret);
                    } catch (IllegalArgumentException e) {
                        throw e;
                    } catch (IllegalAccessException e) {
                    	throw e;
                    } catch (InvocationTargetException e) {
                    	throw e;
                    }
				}
			}
		}
		return map;
	}
	
	/**
	 * 泛型的第一个类型
	 * @param clazz
	 * @return
	 */
	public static Class getGenericClass(Class clazz){
		Object genericClazz = clazz.getGenericSuperclass();
		if(null == genericClazz){
			java.lang.reflect.Type[] genericInterfaces = clazz.getGenericInterfaces();
			if(null != genericInterfaces && genericInterfaces.length > 0){
				genericClazz = genericInterfaces[0];
			}
		}
		if(genericClazz instanceof ParameterizedType){
			Class c = (Class)((ParameterizedType) genericClazz).getActualTypeArguments()[0];
			return c;
		}
		return null;
	}
}



















